package org.jmap.geom;

import java.util.Arrays;
import java.util.Comparator;

public class LineString extends Curve {

	@Override
	public boolean removeComponent(Geometry component) {
		boolean removed = false;
		
		if (this.hasComponents()) {
			if (components.size() > 2) {
				removed = super.removeComponent(component);		
			}
		}

		return removed;
	}
	
	public Segment[] getSortedSegments() {
        int numSeg = this.components.size() - 1;
        Segment[] segments = new Segment[numSeg];
        Point point1, point2;
        for(int i=0; i<numSeg; ++i) {
            point1 = (Point) this.components.get(i);
            point2 = (Point) this.components.get(i + 1);
            if(point1.x < point2.x) {
                segments[i] = new Segment(point1.x, point1.y, point2.x, point2.y);
            } else {
                segments[i] = new Segment(point2.x, point2.y, point1.x, point1.y);
            }
        }
        
        Arrays.sort(segments, new Comparator<Segment>() {
        	@Override
        	public int compare(Segment seg1, Segment seg2) {
        		return (int) (seg1.x1 - seg2.x1);
        	}
		});
        
        return segments;
	}

	@Override
	public boolean intersects(Geometry geometry) {
        boolean intersect = false;

        if (geometry instanceof Point || geometry instanceof LineString) {
            Segment[] segs1 = this.getSortedSegments();
            Segment[] segs2 = new Segment[1];
            if (geometry instanceof Point) {
                segs2[0] = new Segment(((Point)geometry).x, ((Point)geometry).y, ((Point)geometry).x, ((Point)geometry).y);
            } else {
                segs2 = ((LineString) geometry).getSortedSegments();
            }
            
            double seg1x1, seg1x2, seg1y1, seg1y2, seg2y1, seg2y2;
            Segment seg1, seg2;
            // sweep right
            for(int i=0, len=segs1.length; i<len; ++i) {
                seg1 = segs1[i];
                seg1x1 = seg1.x1;
                seg1x2 = seg1.x2;
                seg1y1 = seg1.y1;
                seg1y2 = seg1.y2;
                
                for(int j=0, jlen=segs2.length; j<jlen; ++j) {
                    seg2 = segs2[j];
                    if(seg2.x1 > seg1x2) {
                        // seg1 still left of seg2
                        break;
                    }
                    if(seg2.x2 < seg1x1) {
                        // seg2 still left of seg1
                        continue;
                    }
                    seg2y1 = seg2.y1;
                    seg2y2 = seg2.y2;
                    if(Math.min(seg2y1, seg2y2) > Math.max(seg1y1, seg1y2)) {
                        // seg2 above seg1
                        continue;
                    }
                    if(Math.max(seg2y1, seg2y2) < Math.min(seg1y1, seg1y2)) {
                        // seg2 below seg1
                        continue;
                    }
                    if(AbstractGeometry.segmentsIntersect(seg1, seg2, new SegmentIntersectOptions(null, 0.0d))) {
                        intersect = true;
                        break;
                    }
                }
            }
        } else {
            intersect = geometry.intersects(this);
        }
        return intersect;
	}

	@Override
	public boolean intersects(Geometry geometry, boolean edge) {
		// TODO Auto-generated method stub
		return super.intersects(geometry, edge);
	}
	
	
	
	
	
	
}

class Segment {
	double x1, y1, x2, y2;
	
	public Segment(double x1, double y1, double x2, double y2) {
		this.x1 = x1;
		this.y1 = y1;
		this.x2 = x2;
		this.y2 = y2;
	}
}